package br.ufrn.cep.eEtica.integracao.dao;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;


public class GenericDAO {

	EntityManager em;
	EntityManagerFactory emf;
	
	private static GenericDAO dao;
	
	
	public GenericDAO() {
		emf = Persistence.createEntityManagerFactory("eEtica");
	    em = emf.createEntityManager();
	}
	
	
	public static GenericDAO getInstance(){
		if(dao == null || dao.isClosed()){
			dao = new GenericDAO();
			return dao;
		}else{
			return dao;
		}
	}
	
	public boolean isClosed(){
		return !emf.isOpen();
	}
	
	public void closeDao(){
		em.close();
		emf.close();
	}
	
	public <T> T findById(Class<T> entidadeClass, Serializable id) {
		return (T) em.find(entidadeClass, id);
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> find(Class<T> entidadeClass) {
		return em.createQuery(
				"SELECT e FROM " + entidadeClass.getName() + " AS e")
				.getResultList();
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> listarComRestricao(Class<T> entidadeClass,
			String restricao) {
		return em.createQuery(
				"SELECT e FROM " + entidadeClass.getName() + " AS e WHERE "
						+ restricao).getResultList();
	}

	public <T> void persist(T entidade) {
		em.getTransaction().begin();
		em.persist(entidade);
		em.getTransaction().commit();
	}

	public <T> T merge(T entidade) {
		em.getTransaction().begin();
		T t = em.merge(entidade);
		em.getTransaction().commit();
		return t; 
	}

	public <T> void delete(T entidade) {
		em.getTransaction().begin();
		em.remove(entidade);
		em.getTransaction().commit();
	}

	public <T> void deleteById(Class<T> entidadeClass, Serializable id) {
		T entidade = findById(entidadeClass, id);
		em.getTransaction().begin();
		em.remove(entidade);
		em.getTransaction().commit();
	}

}
